package com.netty.chatRoom.protocol;

import com.netty.chapter09.Message;
import com.netty.chatRoom.server.serializer.Serializer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageCodec;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;

@Slf4j
public class MessageCodec extends ByteToMessageCodec<Message> {
    // 自定义魔数 4 字节
    private static final byte[] MAGIC_BUMBER=new byte[]{'X','U','N','M'};

    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, Message message, ByteBuf byteBuf) throws Exception {
        // 将消息传递给外界，需要将内部消息编码
        // 1. 4字节魔数
        byteBuf.writeBytes(MAGIC_BUMBER);
        // 2. 协议版本号，1字节
        byteBuf.writeByte(1);
        // 3. 序列化算法 ，1字节
        byteBuf.writeByte(0);// 0代表用jdk进行序列化 1代表用JSON序列化
        // 4. 指令类型，1字节
        byteBuf.writeByte(message.getMessageType());
        // 5. 请求序号，4字节
        byteBuf.writeInt(message.getSequenceId());
        // 6. 无意义,对齐填充,1字节
        byteBuf.writeByte(0xff);
        // 7. 获取内容的字节数
        byte[] content = Serializer.Algorithm.JAVA.enserialize(message);
        // 8. 数据长度，4字节
        byteBuf.writeInt(content.length);
        // 9. 数据内容
        byteBuf.writeBytes(content);
    }

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        // 将消息传递给外界，需要将内部消息编码
        // 1. 4字节魔数
        int magicNum = byteBuf.readInt();
        // 2. 协议版本号，1字节
        byte version=byteBuf.readByte();
        // 3. 序列化算法 ，1字节
        byte serializerType=byteBuf.readByte();
        // 4. 指令类型，1字节
        byte messageType=byteBuf.readByte();
        // 5. 请求序号，4字节
        int sequenceId = byteBuf.readInt();
        // 6. 无意义,对齐填充,1字节
        byteBuf.readByte();
        // 8. 数据长度，4字节
        int length = byteBuf.readInt();
        // 9. 数据内容
        byte[] content=new byte[length];
        byteBuf.readBytes(content);
        // 进行转化成对象
        Message message = Serializer.Algorithm.JAVA.deserialize(Message.class, content);
        log.debug("{}, {}, {}, {}, {}, {}", magicNum, version, serializerType, messageType, sequenceId, length);
        log.debug("{}", message);
        list.add(message);
    }
}
